package sanshui.system.trade.factory.data;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import sanshui.system.trade.db.entity.*;
import sanshui.system.trade.db.mapper.StockATradeCalMapper;
import sanshui.system.trade.db.mapper.StockTblDailyRtMapper;
import sanshui.system.trade.db.mapper.TradeDataTblMapper;
import sanshui.system.trade.db.mapper.TradeTargetCodeMapper;
import sanshui.system.trade.model.TradeTimeDriverModel;
import sanshui.system.trade.pojo.StockInfo;
import sanshui.system.trade.pojo.StockInfoVo;
import sanshui.system.trade.service.IStockInfoService;
import sanshui.system.trade.util.CommonTimeUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class DataFactory {

    @Resource
    RedisTemplate<String , String> redisTemplate;

    @Resource
    TradeDataTblMapper tradeDataTblMapper;
    @Resource
    StockTblDailyRtMapper rtMapper;

    @Resource
    TradeTargetCodeMapper tradeTargetCodeMapper;
    @Resource
    StockATradeCalMapper calMapper;
    @Resource
    IStockInfoService stockInfoService;

    public StockInfoVo next(String code, TradeMarketKey tradeMarketKey){
        String key = code + tradeMarketKey.name();
        String codeInfoString = redisTemplate.opsForValue().get(key);

        try {
            StockInfoVo stockInfoVo = JSONObject.parseObject(codeInfoString, StockInfoVo.class);
            log.info("获取当前信息, code:{}, price:{}", stockInfoVo.getTsCode(), stockInfoVo.getPrice());
            return stockInfoVo;
        } catch (Exception e){
            log.error("数据解析失败, code:{}", code, e);
        }
        return null;
    }

    public List<String> loadIndexTargetCode(String indexCode){
        return new ArrayList<>();
    }

    public StockInfoVo next(String code, DataLevelKey dataLevelKey){
        String key = code + dataLevelKey.name();
        String codeInfoString = redisTemplate.opsForValue().get(key);

        try {
            StockInfoVo stockInfoVo = JSONObject.parseObject(codeInfoString, StockInfoVo.class);
            log.info("获取当前信息, code:{}, price:{}", stockInfoVo.getTsCode(), stockInfoVo.getPrice());
            return stockInfoVo;
        } catch (Exception e){
            log.error("数据解析失败, code:{}", code, e);
        }
        return null;
    }

    public List<StockInfoVo> getHisStockInfo(String code, String startDate, String endDate){
        String[] split = code.split("\\.");
        String market;
        String codeS;
        if (split.length == 2){
            market = split[1].toLowerCase();
            codeS = split[0];
            return tradeDataTblMapper.selectHisData(codeS, market, startDate, endDate);

        } else {
            return null;
        }
    }

    /**
     * 获取实时标的信息
     * */
    public List<StockInfo> getStockInfoRt(List<String> targetCodes, LocalDateTime timestamp, TradeMarketKey tradeMarketKey){
//        List<StockInfoVo> his = tradeDataTblMapper.selectCurrentRtData(targetCodes, CommonTimeUtil.getNowTime16(timestamp), tradeMarketKey.name());
        List<StockInfoVo> his = tradeDataTblMapper.selectShunShiData(CommonTimeUtil.getNowTime8(timestamp), targetCodes, CommonTimeUtil.getNowTime8(timestamp));

        List<StockInfo> res =  new ArrayList<>();
        for (StockInfoVo hi : his) {
            StockInfo stockInfo = new StockInfo();
            stockInfo.setPrice(Double.valueOf(hi.getPrice()* 100).longValue() );
            stockInfo.setClose(Double.valueOf(hi.getPrice()* 100).longValue() );
            stockInfo.setVol(Double.valueOf(hi.getVolume()* 100).longValue() );
            stockInfo.setAmount(Double.valueOf(hi.getAmount()* 100).longValue() );

            stockInfo.setDataSrc(hi.getDataSrc());
            stockInfo.setTradeDate(hi.getTradeDate());
            stockInfo.setTsName(hi.getTsName());
            stockInfo.setTsCode(hi.getTsCode().toUpperCase());
            stockInfo.setTradeTime(hi.getTradeTime());
            res.add(stockInfo);
        }
        return res;

    }

    public List<TradeTargetCode> getTargetCodeAgu(Long workerId){
        return stockInfoService.findTargetStock(workerId);
    }

    public List<TradeTimeDriverModel> getDriverTime(String startTime, String endTime, String frequency){
        if (Strings.isEmpty(startTime)){
            return new ArrayList<>();
        }

        StockATradeCalExample example = new StockATradeCalExample();
        StockATradeCalExample.Criteria criteria = example.createCriteria();
        criteria.andCalDateGreaterThanOrEqualTo(startTime);
        if (Strings.isNotEmpty(endTime)){
            criteria.andCalDateLessThan(endTime);
        }
        criteria.andIsOpenEqualTo("1");
        example.setOrderByClause("cal_date asc");
        List<StockATradeCal> stockATradeCals = calMapper.selectByExample(example);

        List<TradeTimeDriverModel> res = new ArrayList<>();

        if ("1d".equalsIgnoreCase(frequency)){
            for (StockATradeCal stockATradeCal : stockATradeCals) {
                TradeTimeDriverModel driverModel = new TradeTimeDriverModel();
                LocalDateTime timestamp8 = CommonTimeUtil.getTimestamp8(stockATradeCal.getCalDate());
                timestamp8 = LocalDateTime.of(
                        timestamp8.getYear(), timestamp8.getMonth(), timestamp8.getDayOfMonth()
                        , 14, 40, 0);
                driverModel.setDriverTime(timestamp8);
                res.add(driverModel);
            }
        }
        return res;
    }

    public List<TradeTimeDriverModel> getDriverTimeIn1Day(String startTime, String endTime, String HHmmss){
        if (Strings.isEmpty(startTime)){
            return new ArrayList<>();
        }

        StockATradeCalExample example = new StockATradeCalExample();
        StockATradeCalExample.Criteria criteria = example.createCriteria();
        criteria.andCalDateGreaterThanOrEqualTo(startTime);
        if (Strings.isNotEmpty(endTime)){
            criteria.andCalDateLessThan(endTime);
        }
        criteria.andIsOpenEqualTo("1");
        example.setOrderByClause("cal_date asc");
        List<StockATradeCal> stockATradeCals = calMapper.selectByExample(example);

        List<TradeTimeDriverModel> res = new ArrayList<>();

        for (StockATradeCal stockATradeCal : stockATradeCals) {
            TradeTimeDriverModel driverModel = new TradeTimeDriverModel();
            LocalDateTime timestamp8 = CommonTimeUtil.getTimestamp8(stockATradeCal.getCalDate());

            int h = Integer.parseInt(HHmmss.substring(0,2));
            int m = Integer.parseInt(HHmmss.substring(2,4));
            int s = Integer.parseInt(HHmmss.substring(4,6));
            timestamp8 = LocalDateTime.of(
                    timestamp8.getYear(), timestamp8.getMonth(), timestamp8.getDayOfMonth()
                    , h, m, s);
            driverModel.setDriverTime(timestamp8);
            res.add(driverModel);
        }
        return res;
    }

    public boolean isWeekend(LocalDateTime time){
        StockATradeCalExample example = new StockATradeCalExample();
        StockATradeCalExample.Criteria criteria = example.createCriteria();
        criteria.andCalDateEqualTo(CommonTimeUtil.getNowTime8(time));
        criteria.andIsOpenEqualTo("1");
        List<StockATradeCal> stockATradeCals = calMapper.selectByExample(example);
        return stockATradeCals.size() == 0;
    }
}
